const fs = require('fs');
const labelDef = require('./Def');
const BaseLabelLoader = require('../../BaseLabelLoader');

class PaddleLabelLoader extends BaseLabelLoader {
    // 创建label对象
    create(bboxes, segs, labels, scores) {
        let result = [];
        for (let i = 0; i < bboxes.length; i++) {
            let jsonObj = labelDef({
                label_format: 'paddle',
                id: i,
                bbox: bboxes[i]?.length === 4 ? bboxes[i] : [],
                text: labels[i] || '',
                score: scores[i] || 0
            });
            result.push(jsonObj);
        }
        return result;
    }

    // 加载数据
    async load(label_info) {
        // console.log("PaddleLabelLoader::load label_info = ", label_info);
        try {
            const jsonData = fs.readFileSync(label_info.label_path, 'utf8');
            const paddleJson = JSON.parse(jsonData);
            let result = [];

            for (let i = 0; i < paddleJson.length; i++) {
                let paddleAnno = paddleJson[i];
                let bbox = [];

                if (paddleAnno.bbox?.length === 4) {
                    bbox = paddleAnno.bbox;
                } else if (paddleAnno.points) {
                    bbox = this.pointsToBbox(paddleAnno.points);
                }

                // 转换points的格式
                let points = paddleAnno.points.map((point) => {
                    return { x: point[0], y: point[1] };
                })

                // 构建标注对象并添加到结果数组中
                result.push(labelDef({
                    label_format: 'paddle',
                    id: i,
                    bbox: bbox,
                    text: paddleAnno.transcription !== undefined && paddleAnno.transcription !== null ? String(paddleAnno.transcription) : '',
                    points: points || [],
                    score: paddleAnno.score || 0
                }));
            }
            return result;
        } catch (error) {
            console.error(`Error load label ${label_info}, error: `, error);
            return { code: -1, msg: error.message };
        }
    }

    // 保存数据
    async save(label_info) {
        // console.log("PaddleLabelLoader::save label_info = ", label_info);
        let paddleJsonPath = label_info.label_url;
        let paddleJson = await this.fromStudio(label_info);
        fs.writeFileSync(paddleJsonPath, JSON.stringify(paddleJson));

        // 更新数据库信息
        let dataset_id = label_info.dataset_id;
        this.app.db && this.app.db.datasets.updateDataset({ id: dataset_id });
        let list_db = this.app.list_dbs[dataset_id];
        list_db && list_db.pairs.updateLabelPath(label_info.pairs_id);
    }

    // 将点集转换为bbox [x1,y1,x2,y2]
    pointsToBbox(points) {
        if (!points || points.length === 0) return [];
        const xs = points.map(p => Array.isArray(p) ? p[0] : p.x);
        const ys = points.map(p => Array.isArray(p) ? p[1] : p.y);
        return [
            Math.min(...xs),
            Math.min(...ys),
            Math.max(...xs),
            Math.max(...ys)
        ];
    }

    // 从studio格式转换为paddle格式
    async fromStudio(label_info) {
        let labels = label_info.labels;
        let paddleJson = [];

        for (let i = 0; i < labels.length; i++) {
            if (!labels[i]) continue;
            let jsonObj = labels[i].data;

            // 转换points格式(对象转数组)
            let pointsArray = jsonObj.points?.map(p => [p.x, p.y]) || [];

            paddleJson.push({
                transcription: jsonObj.text || '',
                score: jsonObj.score || 0,
                bbox: jsonObj.bbox?.length === 4 ? jsonObj.bbox :
                    (pointsArray.length > 0 ? this.pointsToBbox(pointsArray) : []),
                points: pointsArray
            });
        }
        return paddleJson;
    }
}

module.exports = PaddleLabelLoader;